import subprocess
import re
import sys

def get_audio_stats(video_path):
    # 使用更精确的volumedetect参数
    cmd = [
        'ffmpeg',
        '-i', video_path,
        '-filter_complex', 'volumedetect',
        '-f', 'null',
        '-'
    ]
    
    # 运行FFmpeg并捕获输出
    result = subprocess.run(
        cmd,
        stderr=subprocess.PIPE,
        text=True,
        encoding='utf-8',
        errors='ignore'
    )
    
    # 检查错误
    if result.returncode != 0:
        print("错误：FFmpeg执行失败")
        print(result.stderr)
        sys.exit(1)
    
    # 解析输出结果
    output = result.stderr

    print("FFmpeg 输出:")
    print(output)
    
    # 更健壮的正则表达式匹配
    mean_match = re.search(r"mean_volume:\s*(-?[\d\.]+)\s*dB", output)
    max_match = re.search(r"max_volume:\s*(-?[\d\.]+)\s*dB", output)
    
    # 查找所有直方图条目
    histogram_entries = re.findall(r"histogram_(-?[\d\.]+)dB:\s*(\d+)", output)
    
    # 提取结果
    stats = {
        'mean_db': float(mean_match.group(1)) if mean_match else None,
        'max_db': float(max_match.group(1)) if max_match else None,
        'min_db': find_min_db(histogram_entries) if histogram_entries else None
    }
    
    return stats

def find_min_db(histogram_entries):
    """从直方图数据中找出最小分贝值"""
    min_db = None
    
    # 找出有计数的第一个条目（最小分贝值）
    for db_str, count_str in histogram_entries:
        count = int(count_str)
        if count > 0:
            db_value = float(db_str)
            # 寻找最小的分贝值（数值上最小的负数）
            if min_db is None or db_value < min_db:
                min_db = db_value
    
    return min_db

if __name__ == "__main__":
    if len(sys.argv) != 2:
        print("用法: python audio_stats.py <video_file.mp4>")
        sys.exit(1)
    
    video_file = sys.argv[1]
    stats = get_audio_stats(video_file)
    
    print(f"音频分析结果 ({video_file}):")
    print(f"最低分贝: {stats['min_db'] if stats['min_db'] is not None else 'N/A'} dB")
    print(f"平均分贝: {stats['mean_db'] if stats['mean_db'] is not None else 'N/A'} dB")
    print(f"最高分贝: {stats['max_db'] if stats['max_db'] is not None else 'N/A'} dB")